package com.hhsjdesign.dynamicui.core.property

import android.graphics.Color
import android.view.Gravity
import androidx.annotation.ColorInt
import com.hhsjdesign.dynamicui.utils.ColorUtil
import com.hhsjdesign.dynamicui.utils.optDimen
import org.json.JSONObject
import java.lang.Exception

/**
 * 视图属性基类，这个是和json格式完全相同的数据类型
 */
open class ViewBaseProperty {
    var margin: IntArray = IntArray(4) { 0 }
    var padding: IntArray = IntArray(4) { 0 }
    var radius: FloatArray = FloatArray(4) { 0.0F }
    var size: IntArray = IntArray(4).apply {
        this[0] = 0
        this[1] = -1
        this[2] = 0
        this[3] = -2
    }

    //背景字符串
    var solid: String? = TRANSPARENT//|填充色
    var stokeColor: String? = TRANSPARENT//|边框色
    var stokeWidth: Int = 20//边框宽度

    //背景色
    var solidInt: Int = Color.TRANSPARENT
    var gravity: Int = 0// "center|left|right"

    var layoutGravity: Int = 0
    var statusBarHeight: Int = 0


    /**
     *  计算布局
     */
    private fun computeGravity(value: Int): Int {
        return when (value) {
            Gravity_CENTER -> {
                Gravity.CENTER
            }
            Gravity_TOP_LEFT -> {
                Gravity.TOP.or(Gravity.LEFT)
            }
            Gravity_TOP_CENTER_HORIZONTAL -> {
                Gravity.TOP.or(Gravity.CENTER_HORIZONTAL)
            }
            Gravity_TOP_RIGHT -> {
                Gravity.TOP.or(Gravity.RIGHT)
            }
            Gravity_CENTER_VERTICAL_LEFT -> {
                Gravity.CENTER_VERTICAL.or(Gravity.LEFT)
            }
            Gravity_CENTER_VERTICAL_RIGHT -> {
                Gravity.CENTER_VERTICAL.or(Gravity.RIGHT)
            }
            Gravity_BOTTOM_LEFT -> {
                Gravity.BOTTOM.or(Gravity.LEFT)
            }
            Gravity_BOTTOM_CENTER_HORIZONTAL -> {
                Gravity.BOTTOM.or(Gravity.CENTER_HORIZONTAL)
            }
            Gravity_BOTTOM_RIGHT -> {
                Gravity.BOTTOM.or(Gravity.RIGHT)
            }
            else -> {
                Gravity.CENTER
            }
        }
    }

    //方法，返回Android 中对应的Gravity值
    fun viewGravity(): Int {
        return computeGravity(gravity)
    }

    fun layoutGravity(): Int {
        return computeGravity(layoutGravity)
    }

    companion object {
        const val Gravity_CENTER = 0
        const val Gravity_TOP_LEFT = 1
        const val Gravity_TOP_CENTER_HORIZONTAL = 2
        const val Gravity_TOP_RIGHT = 3
        const val Gravity_CENTER_VERTICAL_LEFT = 4
        const val Gravity_CENTER_VERTICAL_RIGHT = 5
        const val Gravity_BOTTOM_LEFT = 6
        const val Gravity_BOTTOM_CENTER_HORIZONTAL = 7
        const val Gravity_BOTTOM_RIGHT = 8

        //所有的默认都是居左，居上
        const val Gravity_LEFT = Gravity_TOP_LEFT
        const val Gravity_TOP = Gravity_TOP_LEFT
        const val Gravity_BOTTOM = Gravity_BOTTOM_LEFT
        const val Gravity_CENTER_VERTICAL = Gravity_CENTER_VERTICAL_LEFT
        const val Gravity_CENTER_HORIZONTAL = Gravity_TOP_CENTER_HORIZONTAL
        const val Gravity_RIGHT = Gravity_TOP_RIGHT


        const val PADDING: String = "padding"
        const val MARGIN: String = "margin"
        const val RADIUS: String = "radius"
        const val SIZE: String = "size"
        const val SOLID: String = "solid"
        const val STROKE: String = "stroke"
        const val STROKE_WIDTH: String = "strokeWidth"
        const val TRANSPARENT: String = "transparent"
        const val STATUS_BAR_HEIGHT: String = "statusBarHeight"
        const val GRAVITY: String = "gravity"

        @JvmStatic
        fun fromJSON(jo: JSONObject?): ViewBaseProperty {

            return ViewBaseProperty().apply {
                jo?.let {
                    var array = jo.optJSONArray(PADDING)
                    if (array != null) {
                        this.padding[0] = array.optDimen(0)
                        this.padding[1] = array.optDimen(1)
                        this.padding[2] = array.optDimen(2)
                        this.padding[3] = array.optDimen(3)
                    }

                    array = jo.optJSONArray(MARGIN)
                    if (array != null) {
                        this.margin[0] = array.optDimen(0)
                        this.margin[1] = array.optDimen(1)
                        this.margin[2] = array.optDimen(2)
                        this.margin[3] = array.optDimen(3)
                    }

                    array = jo.optJSONArray(RADIUS)
                    if (array != null) {
                        this.radius[0] = array.optDimen(0).toFloat()
                        this.radius[1] = array.optDimen(1).toFloat()
                        this.radius[2] = array.optDimen(2).toFloat()
                        this.radius[3] = array.optDimen(3).toFloat()
                    }

                    array = jo.optJSONArray(SIZE)
                    if (array != null) {
                        this.size[0] = array.optInt(0)
                        this.size[1] = array.optDimen(1)
                        this.size[2] = array.optInt(2)
                        this.size[3] = array.optDimen(3)
                    }

                    this.solid = jo.optString(SOLID, TRANSPARENT)
                    this.solidInt = ColorUtil.parseColor(jo.optString(SOLID, TRANSPARENT))
                    this.statusBarHeight = jo.optInt(STATUS_BAR_HEIGHT, 0)
                    this.gravity = jo.optInt(GRAVITY, 0)
                }
            }
        }

        @JvmStatic
        fun parseColor(colorString: String): Int {
            try {
                val color = colorString.replace("rgba(", "").replace(")", "").split(",")
                val colorInt: Int = color[0].toInt().shl(16) + color[1].toInt()
                    .shl(8) + color[0].toInt() + (color[4].toFloat() * 255).toInt().shl(24)//A
                return colorInt
            } catch (e: Exception) {
            }
            return 0
        }
    }

    fun toShapeProperty(): ShapeProperty {
        return ShapeProperty().apply {
            //margin
            this.margin[0] = this@ViewBaseProperty.margin[0]
            this.margin[1] = this@ViewBaseProperty.margin[1]
            this.margin[2] = this@ViewBaseProperty.margin[2]
            this.margin[3] = this@ViewBaseProperty.margin[3]
            //padding
            this.padding[0] = this@ViewBaseProperty.padding[0]
            this.padding[1] = this@ViewBaseProperty.padding[1]
            this.padding[2] = this@ViewBaseProperty.padding[2]
            this.padding[3] = this@ViewBaseProperty.padding[3]
            //圆角
            this.radius[0] = this@ViewBaseProperty.radius[0]
            this.radius[1] = this@ViewBaseProperty.radius[1]
            this.radius[2] = this@ViewBaseProperty.radius[2]
            this.radius[3] = this@ViewBaseProperty.radius[3]
            //尺寸
            this.widthType = this@ViewBaseProperty.size[0]
            this.heightType = this@ViewBaseProperty.size[2]
            this.width = this@ViewBaseProperty.size[1]
            this.height = this@ViewBaseProperty.size[3]
            //颜色
            if (this@ViewBaseProperty.solid == TRANSPARENT) {
                this.backgroundColor = Color.TRANSPARENT
            } else {
                this.backgroundColor = Color.parseColor(this@ViewBaseProperty.solid)
            }
            //是否预留状态栏高度，一般只会在顶部导航组件或者可以滚到状态栏下面的第一个组件考虑这个参数
            this.statusBarHeight = this@ViewBaseProperty.statusBarHeight
        }
    }

    class Builder {

        //尺寸
        var size: IntArray = IntArray(4).apply {
            this[0] = 0
            this[1] = -1 //match parent
            this[2] = 0
            this[3] = -2 //wrap content
        }

        //外间距
        var margin: IntArray = IntArray(4) { 0 }

        //内间距
        var padding: IntArray = IntArray(4) { 0 }

        //背景色
        var backgroundColor: Int = Color.TRANSPARENT

        constructor()


        //宽
        fun width(widthMode: Int, widthValue: Int): Builder {
            this.size[0] = widthMode
            this.size[1] = widthValue
            return this
        }

        //高
        fun height(heightMode: Int, heightValue: Int): Builder {
            this.size[2] = heightMode
            this.size[3] = heightValue
            return this
        }

        //背景颜色
        fun backgroundColor(@ColorInt color: Int): Builder {
            this.backgroundColor = color
            return this
        }

        //外间距
        fun margin(left: Int, top: Int, right: Int, bottom: Int): Builder {
            this.margin[0] = left
            this.margin[1] = top
            this.margin[2] = right
            this.margin[3] = bottom
            return this
        }

        //内间距
        fun padding(left: Int, top: Int, right: Int, bottom: Int): Builder {
            this.padding[0] = left
            this.padding[1] = top
            this.padding[2] = right
            this.padding[3] = bottom
            return this
        }

        fun build(): ViewBaseProperty {
            return ViewBaseProperty().apply {
                this.solidInt = this@Builder.backgroundColor
                this.margin[0] = this@Builder.margin[0]
                this.margin[1] = this@Builder.margin[1]
                this.margin[2] = this@Builder.margin[2]
                this.margin[3] = this@Builder.margin[3]
            }
        }
    }
}